---
title: "Getting Started"
sidebar:
  order: 1
---

import { dedent } from "ts-dedent"
import Code from '#/components/Code.astro'
import DownloadFile from "#/components/DownloadFile.astro"
import { Tabs, TabItem } from "@astrojs/starlight/components"
import FunctionResult from '#/components/FunctionResult.astro'
import { chainVersion } from '#/lib/constants/versions.ts'

This guide is intended for validators running on bare-metal servers and explains how Union releases work. Check out the [NixOS](/infrastructure/node-operators/nixos/) and the [Kubernetes](/infrastructure/node-operators/kubernetes/) guide for more production-ready deployments.

Validators are the backbone of the network. Becoming one requires significant token bonding and delegations, and is not intended for non-power users.

## Obtaining uniond

You can obtain `uniond` from a recent [release](https://github.com/unionlabs/union/releases/latest).

:::caution

Double-check the version and architecture in the link before downloading.

:::

<Tabs syncKey="uniond-release">
  <TabItem label="x86_64-linux">
    ```sh frame="none"
    curl --output uniond --location https://github.com/unionlabs/union/releases/download/$UNIOND_VERSION/uniond-release-x86_64-linux
    ```
    *Where `UNIOND_VERSION` is <FunctionResult result={chainVersion({chainId: 'union-1'}).current} />*

  </TabItem>
  <TabItem label='aarch64-linux'>
    ```sh frame='none'
    curl --output uniond --location https://github.com/unionlabs/union/releases/download/$UNIOND_VERSION/uniond-release-aarch64-linux
    ```
    *Where `UNIOND_VERSION` is <FunctionResult result={chainVersion({chainId: 'union-1'}).current} />*

  </TabItem>
</Tabs>

Verify that the binary works on your server by running:

```sh frame="none"
./uniond --help
```

For convenience, we can add the binary to the `PATH`, to make it callable from anywhere.

```sh frame="none"
mv ./uniond /usr/bin/
```

### Using Docker

We also provide containers in our [package registry](https://github.com/orgs/unionlabs/packages/container/package/uniond-release).

```sh frame="none"
docker pull ghcr.io/unionlabs/uniond-release:$UNIOND_VERSION
```

_Where `UNIOND_VERSION` is <FunctionResult result={chainVersion({chainId: 'union-1'}).current} />_

When running the container, make sure to map a volume to the path passed in `--home` options to ensure data persistence. From here on the guide assumes the usage of a regular binary. The [docker-compose](/infrastructure/node-operators/docker-compose/) section is more suited for docker users.

:::caution

`uniond` is a stateful application and interacts with the file system. Make sure to use [volumes](https://docs.docker.com/storage/volumes/).

:::

## Initialization

We'll need to set up a few configuration files and obtain the <DownloadFile filepath="/genesis.json" filename="genesis.json" /> before we can run the node.

First, set some environment variables, which are used throughout initialization.

```sh title="env.sh"
export CHAIN_ID=union-1
export MONIKER="unionized-goblin"
export KEY_NAME=alice
export GENESIS_URL="https://union.build/genesis.json"
```

Then we'll have `uniond` initialize our data and configuration directories. By default, `/User/{USER}/.uniond` is used.

```sh frame="none"
uniond init $MONIKER --chain-id $CHAIN_ID
```

### Genesis Configuration

Download the `genesis.json` and copy it to your `uniond` home directory.

```sh frame="none"
curl $GENESIS_URL | jq '.result.genesis' > ~/.union/config/genesis.json
```

### Creating a Validator

To join as a validator, you need to create a proof of possession for your consensus key and submit a creation transaction. You can do this from the command line with `uniond`.

1) Add a wallet that holds Union tokens.

```sh frame="none"
uniond keys add $KEY_NAME --recover
```

:::caution

For production usage, we recommend not storing the wallet on a server.

:::

2) Create a Validator JSON File

```sh frame="none"
touch validator.json
```

Add the following content to the file:

```json title="validator.json"
{
	"pubkey": <PUBKEY>,
	"amount": "1000000au",
	"moniker": "<MONIKER>",
	"identity": "optional identity signature (ex. UPort or Keybase)",
	"website": "validator's (optional) website",
	"security": "validator's (optional) security contact email",
	"details": "validator's (optional) details",
	"commission-rate": "0.1",
	"commission-max-rate": "0.2",
	"commission-max-change-rate": "0.01",
	"min-self-delegation": "1"
}
```

Replacing:

- `<PUBKEY>` with the result of running `uniond comet show-validator`
- `<MONIKER>` with your moniker
- And the optional content with your preferred details

3) Create a Proof of Possession

:::note

This step is specific to the Union network, other Cosmos based chains do not currently replicate this process.

:::

Assuming your private validator key is in the default location:

<Tabs>
  <TabItem label='uniond-release'>
    ```sh frame="none"
	export PRIV_KEY=$(jq -r '.priv_key.value' ~/.union/config/priv_validator_key.json)
	export POSSESSION_PROOF=$(uniond prove-possession "$PRIV_KEY")
	```
  </TabItem>
  <TabItem label='Unionvisor'>
    ```sh frame="none"
	export PRIV_KEY=$(jq -r '.priv_key.value' ~/.unionvisor/home/config/priv_validator_key.json)
	export POSSESSION_PROOF=$(uniond prove-possession "$PRIV_KEY")
	```
  </TabItem>
</Tabs>

4) Submit a Create Validator Transaction

Then you can submit this file using the `create-union-validator` sub-command:

```sh frame="none"
uniond tx union-staking create-union-validator $VALIDATOR_JSON_PATH $POSSESSION_PROOF \
	--from $KEY_NAME \
	--chain-id union-1
```

_Where `VALIDATOR_JSON_PATH` is the path to your `validator.json`_

:::caution

If you're running a node with a Docker container, your `validator.json` will need to be in a folder accessible by your Docker container.

If you've followed our instructions for setting up either of our Docker images, you should be able to place this file under `/.unionvisor` (for Unionvisor containers) or under `/.union` (for union-release containers).

For example, when creating a validator with `unionvisor`, you can

```sh frame="none"
touch ~/.unionvisor/validator.json

# Then after editing the json content

uniond tx union-staking create-union-validator /.unionvisor/validator.json $POSSESSION_PROOF \
	--from $KEY_NAME \
	--chain-id union-1
```

:::

:::note

If your keys are stored on a machine other than your node, you can pass the `--node-id` flag to override the node ID ensuring it's the one from the node you're making into a validator.

:::

:::note

If your own node isn't set up to accept RPC request, you can send them to another node via the `--node` option.

:::

:::node

Using `--gas auto`, to create a validator is not supported. Please manually provide gas and fees when creating a validator. You can use the fee market module to query the current gas price.

:::

## Systemd Service

We recommend running `uniond` as a systemd service. Create a file in `/etc/systemd/system` called `uniond.service`. Make sure to replace $USER with your username.

```toml frame="none"
[Unit]
Description=uniond
[Service]
Type=simple
Restart=always
RestartSec=1
User=$USER
ExecStart=/usr/bin/uniond start

[Install]
WantedBy=multi-user.target
```

You should be able to view the node logs by executing

```sh frame="none"
sudo journalctl -f --user uniond
```

It's then recommended to back up these files from `~/.union/config` in a secure location:

- `priv_validator_key.json`
- `node_key.json`
